<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 *
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 *
 * @package      FeatherCMS
 * @subpackage   Members
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://julien.portalier.com
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

class Member extends Model
{
	protected $hasMany      = array('Group');
	public    $defaultOrder = 'Member.id DESC';
	
	function login($uid, $pwd)
	{
		$this->id = $uid;
		
		// tries to gets salt
		$salt = $this->field('salt');
		if (empty($salt))
			return false;
		
		// crypts pwd with salt
		list($salt, $cpwd) = $this->__cryptPwd($pwd, $salt);
		
		// tries to identify user
		$this->conditions(array('Member.id' => $uid, 'Member.pwd' => $cpwd));
		$user = $this->find('id, activate');
		
		if (empty($user))
			return false;
		elseif (!empty($user['Member']['activate']))
			return null;
		
		$user['Member']['groups'] =& $user['Group'];
		return $user['Member'];
	}
	
	function ban($member_id, $ban=true)
	{
		$this->saveFields(array(
			'member_id' => $member_id,
			'banned'    => $ban ? 1 : null
		));
	}
	
	// admin
	
	function beforeValidate()
	{
		if ($this->controller->action == 'register')
			$this->data['Member']['user_agreement'] = isset($this->data['Member']['user_agreement']);
		
		if (empty($this->validate))
		{
			$this->validate = array(
				'id' => array(
					Valid::NotEmpty => _('Oops, you forgot to give an username'),
					'/^[_a-zA-Z0-9\-]{3,}$/' => _('This username uses invalid characters.'),
					'validateUnique' => _("This username isn't available, please choose another one.")
				),
				'old_pwd' => array('validateOldPwd' => _('Wrong password.')),
				'pwd'     => array(
					Valid::NotEmpty => _('Oops, you forgot to provide a password.'),
					'/.{5,}/' => _('Your password must be at least be 5 characters long.')
				),
				'pwd2'    => array('ValidatePwd2' => _('Passwords mismatched.')),
				'email'   => array(
					Valid::Email     => _('A valid email is needed to contact you when needed.'),
					'validateUnique' => _('There already is an account for that email.'),
				),
				'user_agreement' => array('/1/' => _('You must agree to the Terms of Use.')),
			);
		}
		return true;
	}
	
	function afterValidate()
	{
		$data =& $this->data['Member'];
		if (!empty($data['pwd']))
		{
			$data['uncrypted_pwd'] = $data['pwd'];
			list($data['salt'], $data['pwd']) = $this->__cryptPwd($data['pwd']);
		}
		if (!empty($data['pwd2']))
		{
			list($data['salt'], $data['pwd2']) = $this->__cryptPwd($data['pwd2'],
				isset($data['salt']) ? $data['salt'] : null);
		}
		return true;
	}
	
	function validateUnique($field, $value)
	{
		if (is_null($this->id))
		{
			$this->conditions(array($field => $value));
			return (false !== $this->field($field, -1));
		}
		return false;
	}
	
	function validateOldPwd()
	{
		$salt = $this->field('salt');
		list($salt, $pwd) = $this->__cryptPwd($this->data['Member']['old_pwd'], $salt);
		
		$this->conditions(array('id' => $this->id, 'pwd' => $pwd));
		$this->recursive = -1;
		$test = $this->find('id');
		
		if (empty($test))
		{
			// error
			$this->data['Member']['old_pwd'] = '';
			$this->data['Member']['pwd'] = '';
			$this->data['Member']['pwd2'] = '';
			return true;
		}
		
		// ok
		return false;
	}
	
	function validatePwd2()
	{
		if ((empty($this->id) or isset($this->data['Member']['old_pwd'])) and $this->data['Member']['pwd'] != $this->data['Member']['pwd2'])
		{
			$this->data['Member']['pwd'] = '';
			$this->data['Member']['pwd2'] = '';
			return true;
		}
		return false;
	}
	
	function beforeSave()
	{
		if (empty($this->id))
		{
			$this->data['Member']['activate'] = md5(mt_rand());
			$this->setBoolean('user_agreement');
		}
		else
		{
			if (empty($this->data['Member']['old_pwd']))
				unset($this->data['Member']['old_pwd']);
			if (empty($this->data['Member']['pwd']))
				unset($this->data['Member']['pwd']);
		}
		
		$this->data['Member']['allow_contact'] = isset($this->data['Member']['allow_contact']);
		return true;
	}
	
	// internals
	
	function __cryptPwd($pwd, $salt=null)
	{
		if (is_null($salt))
			$salt = substr(md5(uniqid(mt_rand(), true)), 0, 5);
		$pwd = sha1($salt.sha1($pwd));
		return array($salt, $pwd);
	}
}
?>